using UnityEngine;
using System.Collections;

public class TP_Animator : MonoBehaviour 
{
	public enum Direction
	{
		Stationary, Forward, Backward, Left, Right,
		LeftForward, RightForward, LeftBackward, RightBackward
	}
		
	public enum CharacterState
	{
		Idle, Running, WalkBackwards, StrafingLeft,StrafingRight, Jumping,	
		Using, Dead, ActionLocked, Attacking, DrawingSword, 
	}
	
	public static TP_Animator Instance;
	
	private CharacterState lastState;
	
	private float AttackRandomizer = 0.0f;
	private Vector3 initialPosition = Vector3.zero;
	private Quaternion initialRotation = Quaternion.identity;
	
	public Direction MoveDirection {get; set;}
	public CharacterState State {get; set;}
	public bool IsDead {get; set;}
	
	
	// Use this for initialization
	void Awake() 
	{
		Instance = this;
		initialPosition = transform.position;
		initialRotation = transform.rotation;	
	}
	
	// Update is called once per frame
	void Update() 
	{
		DetermineCurrentState();
		ProcessCurrentState();
		Debug.Log("Current Character State: " + State.ToString());
	}
	
	public void DetermineCurrentMoveDirection()
	{
		var forward = false;
		var backward = false;
		var left = false;
		var right = false;
		
		if(TP_Motor.Instance.MoveVector.z > 0)
		{
			forward = true;	
		}
		if(TP_Motor.Instance.MoveVector.z < 0)
		{
			backward = true;	
		}
		if(TP_Motor.Instance.MoveVector.x > 0)
		{
			right = true;	
		}
		if(TP_Motor.Instance.MoveVector.x < 0)
		{
			left = true;	
		}
		
		if(forward)
		{
			if(left)
			{
				MoveDirection = Direction.LeftForward;	
			}
			else if(right)
			{
				MoveDirection = Direction.RightForward;	
			}
			else
			{
				MoveDirection = Direction.Forward;	
			}
		}
		else if(backward)
		{
			if(left)
			{
				MoveDirection = Direction.LeftBackward;	
			}
			else if(right)
			{
				MoveDirection = Direction.RightBackward;	
			}
			else
			{
				MoveDirection = Direction.Backward;	
			}
		}
		else if(left)
		{
			MoveDirection = Direction.Left;
		}
		else if(right)
		{
			MoveDirection = Direction.Right;
		}
		else
		{
			MoveDirection = Direction.Stationary;
		}
	}

	void DetermineCurrentState()
	{
		if(State == CharacterState.Dead)
		{
			return;	
		}
		
		if(!TP_Controller.CharacterController.isGrounded)
		{
			if(State != CharacterState.Jumping)
			{
				//Should be falling
			}
		}
		
		//Moving in a specific direction
		if(State != CharacterState.Jumping &&
		   State != CharacterState.Attacking &&
		   State != CharacterState.Using )
		{
			switch(MoveDirection)
			{
			case Direction.Stationary:
				State = CharacterState.Idle;
				break;
			case Direction.Forward:
				State = CharacterState.Running;
				break;
			case Direction.Backward:
				State = CharacterState.WalkBackwards;
				break;
			case Direction.Left:
				State = CharacterState.StrafingLeft;
				break;
			case Direction.Right:
				State = CharacterState.StrafingRight;
				break;
			case Direction.LeftForward:
				State = CharacterState.Running;
				break;
			case Direction.RightForward:
				State = CharacterState.Running;
				break;
			case Direction.LeftBackward:
				State = CharacterState.WalkBackwards;
				break;
			case Direction.RightBackward:
				State = CharacterState.WalkBackwards;
				break;

			}
		}
	}
	
	void ProcessCurrentState()
	{
		switch (State)
		{
		case CharacterState.Idle:
			Idle();
			break;
		case CharacterState.Running:
			Running();
			break;
		case CharacterState.WalkBackwards:
			WalkBackwards();
			break;
		case CharacterState.StrafingLeft:
			StrafingLeft();
			break;
		case CharacterState.StrafingRight:
			StrafingRight();
			break;
		case CharacterState.Jumping:
			Jumping();
			break;
		case CharacterState.Attacking:
			Attacking();
			break;
		case CharacterState.Using:
			Using();
			break;
		case CharacterState.Dead:
			Dying();
			break;
		case CharacterState.ActionLocked:
			break;
		}
	}
	
	#region Character State Methods
	void Idle()
	{
		animation.CrossFade("Combat");
	}
	
	void Running()
	{
		animation.CrossFade("Running");	
	}
	
	void WalkBackwards()
	{
		animation.CrossFade("WalkingBackwards");	
	}
	
	void StrafingLeft()
	{
		animation.CrossFade("StrafingLeft");	
	}
	
	void StrafingRight()
	{
		animation.CrossFade("StrafingRight");	
	}
	
	void Using()
	{
		if(!animation.isPlaying)
		{
			State = CharacterState.Idle;
			animation.CrossFade("Combat");
		}
	}
	
	void Jumping()
	{
		if((!animation.isPlaying && TP_Controller.CharacterController.isGrounded) || 
			TP_Controller.CharacterController.isGrounded)
		{
			if(lastState == CharacterState.Idle)
			{
				State = CharacterState.Idle;
				animation.CrossFade("Combat");
				
			}
			else if(lastState == CharacterState.Running)
			{
				State = CharacterState.Running;
				animation.CrossFade("Running");
			}
			else if(lastState == CharacterState.StrafingLeft)
			{
				State = CharacterState.StrafingLeft;
				animation.CrossFade("StrafingLeft");
			}
			else if(lastState == CharacterState.StrafingRight)
			{
				State = CharacterState.StrafingRight;
				animation.CrossFade("StrafingRight");
			}
			else if(lastState == CharacterState.WalkBackwards)
			{
				State = CharacterState.WalkBackwards;
				animation.CrossFade("WalkingBackwards");
			}
			
		}
		else
		{
			//Else the character is still jumping
			State = CharacterState.Jumping;	
		}
	}

	void Dying()
	{
		IsDead = true;
		State = CharacterState.Dead;
	}
	
	void Attacking()
	{
		//Character is grounded
		if((!animation.isPlaying && TP_Controller.CharacterController.isGrounded))
		{
			if(lastState == CharacterState.Idle)
			{
				State = CharacterState.Idle;
				animation.CrossFade("Combat");		
			}
			else if(lastState == CharacterState.Running)
			{
				State = CharacterState.Running;
				animation.CrossFade("Running");
			}
			else if(lastState == CharacterState.StrafingLeft)
			{
				State = CharacterState.StrafingLeft;
				animation.CrossFade("StrafingLeft");
			}
			else if(lastState == CharacterState.StrafingRight)
			{
				State = CharacterState.StrafingRight;
				animation.CrossFade("StrafingRight");
			}
			else if(lastState == CharacterState.WalkBackwards)
			{
				State = CharacterState.WalkBackwards;
				animation.CrossFade("WalkingBackwards");
			}
			if(lastState == CharacterState.Jumping && TP_Motor.Instance.MoveVector.magnitude == 0)
			{
				State = CharacterState.Idle;
				animation.CrossFade("Combat");
			}
			if(lastState == CharacterState.Jumping && TP_Motor.Instance.MoveVector.magnitude > 0)
			{
				State = CharacterState.Running;
				animation.CrossFade("Running");
			}
		}
		
		//Character is jumping
		else if(!animation.isPlaying)
		{	
			if(lastState == CharacterState.Jumping)
			{	
				State = CharacterState.Jumping;
			}
		}
		else
		{
			State = CharacterState.Attacking;//Still Attacking
		}
		
	}
	#endregion

	#region Start Action Methods
	public void Use()
	{
		State = CharacterState.Using;
		animation.CrossFade("Using");
	}
	
	public void Jump()
	{
		if(!TP_Controller.CharacterController.isGrounded || IsDead || State == CharacterState.Jumping)
		{
			return;	
		}
		lastState = State;
		State = CharacterState.Jumping;
		animation.CrossFade("Jumping");
	}
	
	public void Attack()
	{
		//If already attacking or dead, do nothing
		if(State == CharacterState.Attacking || IsDead)
		{
			return;	
		}
		
		//Randomize attack animation
		AttackRandomizer = Random.value;
		
		//Set State and save lastState
		lastState = State;
		State = CharacterState.Attacking;
		
		//If the character is not ont the ground, play attacking animation
		if(!TP_Controller.CharacterController.isGrounded)
		{
			animation.CrossFade("JumpingAttack");
		}
		
		//Character is grounded, play ground attacks
		else
		{
			if(AttackRandomizer >= 0.0f && AttackRandomizer < 0.2f)
			{
				animation.CrossFade("Chopping2H");	
			}
			else if(AttackRandomizer >= 0.2f && AttackRandomizer < 0.4f)
			{
				animation.CrossFade("Chopping");
			}
			else if(AttackRandomizer >= 0.4f && AttackRandomizer < 0.6f)
			{
				animation.CrossFade("SlashingBackhand");
			}
			else if(AttackRandomizer >= 0.6f && AttackRandomizer < 0.8f)
			{
				animation.CrossFade("Slashing");
			}
			else
			{
				animation.CrossFade("Thrusting");
			}
		}
	}
	
	public void Die()
	{
		//Initialize everything needed to die
		Dying();
		animation.CrossFade("Dying");
		
	}
	
	public void Reset()
	{
		//Reset character
		transform.position = initialPosition;
		transform.rotation = initialRotation;
		IsDead = false;
	}
	#endregion
}